using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Xml;
using WebServiceTool.Models;
using WebServiceTool.Services;
using WebServiceTool.Utilities;

namespace WebServiceTool.ViewModels
{
    /// <summary>
    /// 方法视图模型，用于封装单个WebService方法的视图逻辑
    /// </summary>
    public class MethodDetailViewModel : INotifyPropertyChanged
    {

        #region 字段

        private readonly IWebService _webService;
        private readonly string _wsdlContent;

        private string _responseContent = string.Empty;
        private bool _isHttpRequesting;

        #endregion

        #region 构造函数

        public MethodDetailViewModel(WebServiceOperation operation, IWebService webService, string wsdlContent)
        {
            Operation = operation;
            _webService = webService;

            _wsdlContent = wsdlContent;

            // 初始化命令
            InvokeMethodCommand = new RelayCommand(Execute, CanExecute);
            // 将命令绑定到WebService方法
            Operation.InvokeMethodCommand = InvokeMethodCommand;
        }

        private async void Execute()
        {
            try
            {
                await InvokeMethod();
            }
            catch (Exception ex)
            {
                // 可选：记录日志或显示错误提示
                // 例如：MessageBox.Show($"调用方法时发生错误: {ex.Message}");
                ResponseContent = $"调用方法时发生错误: {ex.Message}";
            }
        }

        private bool CanExecute()
        {
            return !IsHttpRequesting;
        }

        #endregion

        #region 属性

        /// <summary>
        /// WebService方法
        /// </summary>
        public WebServiceOperation Operation { get; }

        /// <summary>
        /// 响应内容
        /// </summary>
        public string ResponseContent
        {
            get => _responseContent;
            set
            {
                _responseContent = value;
                OnPropertyChanged();
            }
        }

        /// <summary>
        /// 是否正在发送请求
        /// </summary>
        public bool IsHttpRequesting
        {
            get => _isHttpRequesting;
            set
            {
                _isHttpRequesting = value;
                OnPropertyChanged(nameof(IsHttpRequesting));
            }
        }

        /// <summary>
        /// 调用方法命令
        /// </summary>
        public ICommand InvokeMethodCommand { get; }

        #endregion

        #region 私有方法 - 命令实现

        /// <summary>
        /// 调用方法
        /// </summary>
        private async Task InvokeMethod()
        {
            IsHttpRequesting = true;
            ResponseContent = $"【{Operation.Name}】方法执行中...";
            try
            {
                var result = await _webService.InvokeMethodAsync(_wsdlContent, Operation.Name, Operation.InputParameters);

                // 检查返回的数据是否是有效的XML
                if (string.IsNullOrWhiteSpace(result))
                {
                    ResponseContent = "调用失败: 服务器返回空响应";
                }
                else
                {
                    // 尝试解析XML来验证它是否有效
                    try
                    {
                        // 格式化XML以便更好地显示
                        ResponseContent = FormatXml(result);
                    }
                    catch (XmlException)
                    {
                        // 如果不是有效的XML，就直接显示原始内容
                        ResponseContent = $"服务器返回非XML格式数据:\n{result}";
                    }
                }
            }
            catch (Exception ex)
            {
                ResponseContent = ex.Message;
            }
            finally
            {
                IsHttpRequesting = false;
            }
        }

        #endregion

        #region 私有方法 - XML格式化

        /// <summary>
        /// 格式化XML字符串以便更好地显示
        /// </summary>
        /// <param name="xml">要格式化的XML字符串</param>
        /// <returns>格式化后的XML字符串</returns>
        private string FormatXml(string xml)
        {
            try
            {
                // 处理HTML实体，将&lt;和&gt;转换为<和>
                xml = xml.Replace("&lt;", "<").Replace("&gt;", ">");

                var doc = new XmlDocument();
                doc.LoadXml(xml);

                using (var stringWriter = new StringWriter())
                {
                    using (var xmlTextWriter = new XmlTextWriter(stringWriter))
                    {
                        xmlTextWriter.Formatting = Formatting.Indented;
                        xmlTextWriter.Indentation = 2;
                        doc.WriteTo(xmlTextWriter);
                        return stringWriter.ToString();
                    }
                }
            }
            catch (Exception)
            {
                return xml; // 如果格式化失败，返回原始XML
            }
        }

        #endregion

        #region INotifyPropertyChanged实现

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

    }
}